
package com.borqs.music.ui.online;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ExpandableListActivity;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.borqs.music.DownloadService;
import com.borqs.music.IDownloadService;
import com.borqs.music.R;
import com.borqs.music.model.DownloadItem;
import com.borqs.music.util.MusicUtils;
import com.borqs.music.util.MyLogger;

public class OnlineDownloadingListActivity extends ExpandableListActivity implements
        MusicUtils.DownloadDefs {
    private static final int DIALOG_LOADING_DOWNLOAD_TASK = 10;
    private static final int REFRESH = 1;
    private static final MyLogger logger = MyLogger.getLogger("OnlineDownloadingListActivity");
    private List<List<DownloadItem>> mDownloadList;
    private DownloadExpandableListAdapter mAdapter;
    private DownLoadHandler mHandler;
    private IDownloadService mDownloadService;

    private ServiceConnection serviceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mDownloadService = (IDownloadService) service;
            initListView(mDownloadService.getDownloadingTaskList());
            removeDialog(DIALOG_LOADING_DOWNLOAD_TASK);
            Message msg = mHandler.obtainMessage(REFRESH);
            mHandler.sendMessage(msg);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mDownloadService = null;
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setTitle(R.string.online_downloading_list_title);
        showDialog(DIALOG_LOADING_DOWNLOAD_TASK);
        this.bindService(new Intent(this, DownloadService.class), serviceConnection,
                BIND_AUTO_CREATE);
        mHandler = new DownLoadHandler();

    }

    @Override
    protected Dialog onCreateDialog(int id) {
        AlertDialog dialog = null;
        switch (id) {
            case DIALOG_LOADING_DOWNLOAD_TASK:
                dialog = new ProgressDialog(this);
                dialog.setIcon(android.R.drawable.ic_dialog_info);
                dialog.setTitle(R.string.dialog_loading_info_title);
                dialog.setMessage(getString(R.string.dialog_loading_info_message));
                dialog.setCancelable(true);
                return dialog;
            default:
                break;
        }
        return super.onCreateDialog(id);
    }

    @Override
    protected void onDestroy() {
        if (null != serviceConnection) {
            this.unbindService(serviceConnection);
        }
        super.onDestroy();
    }

    private void initListView(List<DownloadItem> downloadItemList) {
        List<DownloadItem> downloadingList = new ArrayList<DownloadItem>();
        List<DownloadItem> waitingList = new ArrayList<DownloadItem>();
        List<DownloadItem> failedList = new ArrayList<DownloadItem>();
        for (DownloadItem item : downloadItemList) {
            if (DOWNLOAD_TASK_RUNNING == item.status) {
                downloadingList.add(item);
            } else if (DOWNLOAD_TASK_WAITING == item.status) {
                waitingList.add(item);
            } else if (DOWNLOAD_TASK_FAILED == item.status) {
                failedList.add(item);
            }
        }
        mDownloadList = new ArrayList<List<DownloadItem>>(3);
        mDownloadList.add(downloadingList);
        mDownloadList.add(waitingList);
        mDownloadList.add(failedList);
        List<Integer> groupList = new ArrayList<Integer>();
        groupList.add(R.string.list_group_downloading);
        groupList.add(R.string.list_group_waitingg);
        groupList.add(R.string.list_group_failed);

        mAdapter = new DownloadExpandableListAdapter(
                OnlineDownloadingListActivity.this, groupList, mDownloadList);
        OnlineDownloadingListActivity.this.setListAdapter(mAdapter);
        getExpandableListView().expandGroup(0);
        getExpandableListView().expandGroup(1);
        getExpandableListView().expandGroup(2);
    }

    private class ListViewItemHolder {
        ImageView icon;
        TextView textShowname;
        ProgressBar progress;
        ImageButton deleteButton;
        ImageButton retryButton;
        TextView downloadSize;
    }

    class DownloadExpandableListAdapter extends BaseExpandableListAdapter {
        private LayoutInflater mInflater;
        private List<Integer> groupList;
        private List<List<DownloadItem>> downloadList;
        private Context mContext;

        public DownloadExpandableListAdapter(Context context, List<Integer> groupList,
                List<List<DownloadItem>> downloadList) {
            this.mContext = context;
            mInflater = LayoutInflater.from(context);
            this.groupList = groupList;
            this.downloadList = downloadList;
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return downloadList.get(groupPosition).get(childPosition);
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return downloadList.get(groupPosition).get(childPosition).getId();
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            return downloadList.get(groupPosition).size();
        }

        public TextView getGenericView() {
            // Layout parameters for the ExpandableListView
            AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, px2pid(64));

            TextView textView = new TextView(OnlineDownloadingListActivity.this);
            textView.setLayoutParams(lp);
            // Center the text vertically
            textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
            // Set the text starting position
            textView.setPadding(px2pid(40), 0, 0, 0);
            return textView;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
                View convertView, ViewGroup parent) {
            final DownloadItem item = (DownloadItem) getChild(groupPosition, childPosition);
            ListViewItemHolder holder = null;
            if (convertView != null) {
                holder = (ListViewItemHolder) convertView
                        .getTag(R.layout.download_running);
            } else {
                convertView = (LinearLayout) mInflater.inflate(
                        R.layout.download_running, parent,
                        false);
                holder = new ListViewItemHolder();
                holder.icon = (ImageView) convertView.findViewById(R.id.listicon1);
                holder.textShowname = (TextView) convertView.findViewById(R.id.showname);
                holder.progress = (ProgressBar) convertView.findViewById(R.id.download_progress);
                holder.deleteButton = (ImageButton) convertView
                        .findViewById(R.id.delete_button);
                holder.retryButton = (ImageButton) convertView
                .findViewById(R.id.retry_button);
                holder.downloadSize = (TextView) convertView.findViewById(R.id.download_size);

                convertView.setTag(R.layout.download_running, holder);
            }
            holder.deleteButton.setTag(R.string.button_text_remove);

            holder.textShowname.setText(item.getTitle());
            holder.retryButton.setVisibility(View.GONE);
            if (item.status == DOWNLOAD_TASK_RUNNING) {
                holder.progress.setVisibility(View.VISIBLE);
                holder.downloadSize.setVisibility(View.VISIBLE);
                holder.icon.setBackgroundResource(R.drawable.list_music_download);
                holder.progress.setMax((int) item.max);
                holder.progress.setProgress((int) item.value);
                // set downloadsize like 1.00M/2.00M
                double downloadedSize = (double) item.max / 1024 / 1024;
                double fileSize = (double) item.value / 1024 / 1024;
                String sizeDes = mContext.getString(R.string.text_downloaded_size, fileSize,
                        downloadedSize);
                holder.downloadSize.setText(sizeDes);
            } else {
                holder.progress.setVisibility(View.GONE);
                holder.downloadSize.setVisibility(View.GONE);
                if (item.status == DOWNLOAD_TASK_FAILED) {
                    holder.icon.setBackgroundResource(R.drawable.list_music_failed);
                    holder.retryButton.setVisibility(View.VISIBLE);
                    holder.retryButton.setTag(R.string.button_text_retry);
                } else {
                    holder.icon.setBackgroundResource(R.drawable.list_music_wait);
                }
            }

            final int gp = groupPosition;
            final int cp = childPosition;
            OnClickListener listener = new OnClickListener() {

                @Override
                public void onClick(View v) {
                    final int tag = (Integer) v.getTag();
                    int title = R.string.dialog_remove_item_from_list_title;
                    int msg = R.string.dialog_remove_item_from_list_message;
                    if (R.string.button_text_retry == tag) {
                        title = R.string.dialog_retry_download_title;
                        msg = R.string.dialog_retry_download_message;
                    }
                    final DownloadItem item = downloadList.get(gp).get(cp);
                    new AlertDialog.Builder(OnlineDownloadingListActivity.this)
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .setTitle(title)
                            .setMessage(msg)
                            .setNeutralButton(android.R.string.ok,
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            if (!downloadList.get(gp).contains(item)) {
                                                return;
                                            }
                                            downloadList.get(gp).remove(item);
                                            if (R.string.button_text_retry == tag) {
                                                logger.d("retry download FileName:" + item.getFileName());
                                                mDownloadService.startNewDownloadTask(item);
                                                Message msg = mHandler.obtainMessage(REFRESH);
                                                mHandler.sendMessage(msg);
                                            } else {
                                                logger.d("cancel download FileName:" + item.getFileName());
                                                mDownloadService.cancelDownloadTask(item);
                                            }
                                            mAdapter.notifyDataSetChanged();
                                        }

                                    }).setNegativeButton(android.R.string.cancel, null).show();
                }
            };
            holder.deleteButton.setOnClickListener(listener);
            holder.retryButton.setOnClickListener(listener);
            return convertView;
        }

        @Override
        public Object getGroup(int groupPosition) {
            return groupList.get(groupPosition);
        }

        @Override
        public int getGroupCount() {
            return groupList.size();
        }

        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
                ViewGroup parent) {
            TextView textView = getGenericView();
            textView.setText(groupList.get(groupPosition));
            return textView;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }

    }

    private class DownLoadHandler extends Handler {

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case REFRESH:
                    long next = refreshNow();
                    queueNextRefresh(next);
                    break;
            }
        }

        private void queueNextRefresh(long delay) {
            if (null != mDownloadService && mDownloadService.isDownloading()) {
                Message msg = mHandler.obtainMessage(REFRESH);
                mHandler.removeMessages(REFRESH);
                mHandler.sendMessageDelayed(msg, delay);
            }
        }

        private long refreshNow() {
            mDownloadList.get(0).clear();
            mDownloadList.get(1).clear();
            mDownloadList.get(2).clear();
            List<DownloadItem> downloadItemList = mDownloadService.getDownloadingTaskList();
            for (DownloadItem item : downloadItemList) {
                if (DOWNLOAD_TASK_RUNNING == item.status) {
                    mDownloadList.get(0).add(item);
                } else if (DOWNLOAD_TASK_WAITING == item.status) {
                    mDownloadList.get(1).add(item);
                } else if (DOWNLOAD_TASK_FAILED == item.status) {
                    mDownloadList.get(2).add(item);
                }
            }
            mAdapter.notifyDataSetChanged();

            return 500;
        }
    }

    public int px2pid(float pxValue) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (pxValue * scale + 0.5f);
    }

}
